#include "ipc.h"
#include "types.h"
#include <iostream>
#include <thread>
#include <chrono>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <fstream>
#include <sstream>
#include <sys/stat.h>

class CaptureProcess {
private:
    SystemState current_state = SystemState::IDLE;
    std::thread capture_thread_a, capture_thread_b;
    std::queue<FrameInfo> cache_a, cache_b;
    std::mutex cache_mutex_a, cache_mutex_b;
    std::condition_variable cv;
    bool running = true;
    CaptureConfig config_a, config_b;
    bool strike_detected = false;
    uint64_t strike_timestamp = 0;
    bool tail_capture_complete = false;

public:
    CaptureProcess() {
        // 初始化相机配置
        config_a = {CameraId::CAMERA_A, 640, 480, 25, 5, 3, 2};
        config_b = {CameraId::CAMERA_B, 1920, 1080, 25, 6, 0.5, 5.5};
    }

    void run() {
        sd_journal_print(LOG_INFO, "相机采集进程启动");

        // 启动消息接收线程
        std::thread msg_thread(&CaptureProcess::message_loop, this);
        sd_journal_print(LOG_INFO, "启动CAPTURE_SOCKET消息接收线程成功");
        // 等待进入采集状态
        sd_journal_print(LOG_INFO, "进入等待进入采集状态");
        std::unique_lock<std::mutex> lock(cache_mutex_a);
        cv.wait(lock, [this] { return current_state == SystemState::CAPTURE; });
        
        // 启动采集线程
        sd_journal_print(LOG_INFO, "A/B相机采集信线程启动完成");
        capture_thread_a = std::thread(&CaptureProcess::capture_loop, this, config_a);
        capture_thread_b = std::thread(&CaptureProcess::capture_loop, this, config_b);

        msg_thread.join();
        if (capture_thread_a.joinable()) capture_thread_a.join();
        if (capture_thread_b.joinable()) capture_thread_b.join();
    }

private:
    void message_loop() {
        Message msg;
        while (running) {
            if (receive_message(CAPTURE_SOCKET, msg)) {
                handle_message(msg);
            }
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
    }

    void handle_message(const Message& msg) {
        switch (msg.type) {
            case MessageType::STATE_CHANGE:
                {
                    current_state = msg.state;
                    if (current_state == SystemState::CAPTURE) {
                        cv.notify_all();
                        strike_detected = false;
                        tail_capture_complete = false;
                    } else if (current_state == SystemState::IDLE) {
                        clear_caches();
                    }
                    break;
                }
            
            case MessageType::STRIKE_DETECTED:
                {
                    if (current_state == SystemState::CAPTURE) {
                        strike_detected = true;
                        strike_timestamp = msg.strike.timestamp;
                        sd_journal_print(LOG_INFO, "收到击球事件" );
                    }
                    break;
                }

            case MessageType::HEARTBEAT:
                {// 响应心跳
                    Message response;
                    response.type = MessageType::HEARTBEAT;
                    response.timestamp = get_current_timestamp();
                    send_message(SUPERVISOR_SOCKET, response);
                    //sd_journal_print(LOG_INFO, "向状态机控制进程发送心跳包");
                
                break;
                }

            default:
                break;
        }
    }

    void capture_loop(CaptureConfig config) {
        uint32_t frame_num = 0;
        auto& cache = (config.cam_id == CameraId::CAMERA_A) ? cache_a : cache_b;
        auto& mutex = (config.cam_id == CameraId::CAMERA_A) ? cache_mutex_a : cache_mutex_b;
        uint32_t max_frames = config.cache_duration * config.fps;
        uint32_t post_strike_frames = config.post_strike * config.fps;
        uint32_t post_strike_counter = 0;

        std::cout << "开始录制相机：   " 
                  << (config.cam_id == CameraId::CAMERA_A ? "A" : "B") << "\n";
        sd_journal_print(LOG_INFO, "开始录制相机： %c", 
            (config.cam_id == CameraId::CAMERA_A ? "A" : "B"));
        while (running && current_state != SystemState::IDLE) {
            uint64_t timestamp = get_current_timestamp();
            
            // 模拟采集帧数据
            FrameInfo frame;
            frame.cam_id = config.cam_id;
            frame.timestamp = timestamp;
            frame.frame_num = frame_num++;
            //frame.path = save_frame(frame);
            frame.path = (const char*)" ";

            // 缓存管理
            std::lock_guard<std::mutex> lock(mutex);
            cache.push(frame);
            
            // 保持缓存大小
            if (cache.size() > max_frames) {
                cache.pop();
            }

            // 处理击球事件后的尾采集
            if (strike_detected) {
                if (current_state != SystemState::TAIL_CAPTURE) {
                    // 通知 supervisor 进入尾采集状态
                    Message msg;
                    msg.type = MessageType::STATE_CHANGE;
                    msg.state = SystemState::TAIL_CAPTURE;
                    msg.timestamp = timestamp;
                    send_message(SUPERVISOR_SOCKET, msg);
                    sd_journal_print(LOG_INFO, "向状态机控制进程发送进入尾采集状态");
                }

                post_strike_counter += 0.5;
                if (post_strike_counter >= post_strike_frames) {
                    // 此相机尾采集完成
                    if (config.cam_id == CameraId::CAMERA_A) {
                        sd_journal_print(LOG_INFO, "相机 A 尾 采集 完成");
                    } else {
                        sd_journal_print(LOG_INFO, "相机 B 尾 采集 完成");
                        // 最后一个相机完成后通知 supervisor
                        Message msg;
                        msg.type = MessageType::CAPTURE_FINISHED;
                        msg.timestamp = timestamp;
                        send_message(SUPERVISOR_SOCKET, msg);
                        tail_capture_complete = true;
                    }
                    break;
                }
            }

            // 控制帧率
            std::this_thread::sleep_for(std::chrono::milliseconds(1000 / config.fps));
        }
    }

    void clear_caches() {
        std::lock_guard<std::mutex> lock_a(cache_mutex_a);
        std::lock_guard<std::mutex> lock_b(cache_mutex_b);
        while (!cache_a.empty()) cache_a.pop();
        while (!cache_b.empty()) cache_b.pop();
    }

    std::string save_frame(const FrameInfo& frame) {
        // 模拟保存帧数据到文件
        std::stringstream ss;
        ss << "/tmp/cam_" 
           << (frame.cam_id == CameraId::CAMERA_A ? "a_" : "b_")
           << frame.frame_num << ".bin";
        
        std::ofstream ofs(ss.str(), std::ios::binary);
        // 写入模拟数据
        char dummy_data[1024] = {0};
        ofs.write(dummy_data, sizeof(dummy_data));
        
        return ss.str();
    }

    uint64_t get_current_timestamp() {
        auto now = std::chrono::system_clock::now();
        auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
            now.time_since_epoch()
        );
        return ms.count();
    }
};

int main() {
    try {
        CaptureProcess process;
        process.run();
    } catch (const std::exception& e) {
        std::cerr << "Capture process error: " << e.what() << "\n";
        return 1;
    }
    return 0;
}